package net.threeple.springjdbc.helper;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.CharMatcher;

public class SqlExpression {
	public static String get(String sqlExpression, Map<String, Object> params) {
		Logger logger = LoggerFactory.getLogger(SqlExpression.class);
		int lastIndex = sqlExpression.lastIndexOf("}");
		String whereAfter = sqlExpression.substring(lastIndex + 1);
		int beginIndex = sqlExpression.indexOf("{");
		if(beginIndex < 0) {
			return sqlExpression;
		}
		String sql = sqlExpression.substring(0, beginIndex);
		int cursorIndex = beginIndex;
		int i = 0;
		while(cursorIndex >= 0) {
			int endIndex = sqlExpression.indexOf("}", cursorIndex);
			String condition = new String(i + "=" + i);
			cursorIndex = cursorIndex + 1;
			String expression = sqlExpression.substring(cursorIndex, endIndex);
//			logger.debug("expression: {}", expression);
			for(String param : params.keySet()) {
				if(expression.contains(":" + param) 
						&& isNotNull(params.get(param))) {
//					cursorIndex = cursorIndex + 2;
					condition = expression;
				}
			}
//			logger.debug("condition: {}", condition);
			sql = sql + condition;
			cursorIndex = sqlExpression.indexOf("{", cursorIndex); // 将游标移动到下一个$处
			if((cursorIndex > 0)
					&& ((endIndex + 1) < sqlExpression.length())) { // 这里为了将AND或者OR等加入sql语句
				 sql = sql + sqlExpression.substring(endIndex + 1, cursorIndex);
			}
			i++;
		}
		sql = CharMatcher.WHITESPACE.trimAndCollapseFrom(sql + whereAfter, ' ');
		logger.info("sql: {}", sql);
		return sql;
	}
	
	private static boolean isNotNull(Object object) {
		if(object == null) {
			return false;
		}
		if(object instanceof String) {
			if(("".equals(String.valueOf(object)) 
					|| "%%".equals(String.valueOf(object)))){
				return false;
			}
		}
		if(object instanceof List) {
			Class<?> clazz = object.getClass();
			try {
				Method sizeMethod = clazz.getMethod("size");
				sizeMethod.setAccessible(true);
				int size = (int) sizeMethod.invoke(object);
				return size > 0;
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		return true;
	}
	
	public static void main(String[] args) {
		String sql = "SELECT * FROM t_house WHERE {house_record_date BETWEEN :start AND :end} AND {house_transaction_mode = :mode} AND {house_state IN (:states)} AND a = :name";
		Map<String, Object> params = new HashMap<String, Object>();
		SqlExpression.get(sql, params);
		params.put("start", new Date());
		params.put("end", new Date());
		SqlExpression.get(sql, params);
		params.put("mode", "EFF");
		SqlExpression.get(sql, params);
		params.put("states", Arrays.asList(new String[0]));
		SqlExpression.get(sql, params);
		params.put("states", Arrays.asList(new String[1]));
		SqlExpression.get(sql, params);
		
		
	}
}
